home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / recov / recovProc.c < prev   
C/C++ Source or Header  |  1991-03-20  |  9KB  |  365 lines

  1. /* 
  2.  * recovProc.c --
  3.  *
  4.  *    Recov_Proc is the process that periodically checks the status
  5.  *    of other hosts.  It is pretty simple, but its in its own file
  6.  *    because of the monitor lock needed to synchronize access to
  7.  *    its list of interesting hosts.
  8.  *
  9.  * Copyright 1989 Regents of the University of California
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose and without
  12.  * fee is hereby granted, provided that the above copyright
  13.  * notice appear in all copies.  The University of California
  14.  * makes no representations about the suitability of this
  15.  * software for any purpose.  It is provided "as is" without
  16.  * express or implied warranty.
  17.  */
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: /sprite/src/kernel/recov/RCS/recovProc.c,v 1.14 91/03/20 11:27:32 kupfer Exp $ SPRITE (Berkeley)";
  21. #endif /* not lint */
  22.  
  23. #include <sprite.h>
  24. #include <recov.h>
  25. #include <sync.h>
  26. #include <rpc.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29.  
  30. /*
  31.  * A host is "pinged" (to see when it reboots) at an interval determined by
  32.  * rpcPingSeconds.
  33.  */
  34. int recovPingSeconds = 30;
  35. /*
  36.  * Whether or not to ping at absolute intervals instead of 30 after the last
  37.  * ping finished.  This is used for testing the affects of the synchronization
  38.  * of client pinging on the servers.  The condition variable gets its 
  39.  * own lock because that seemed cleaner than using the monitor lock 
  40.  * (the condition variable has nothing to do with the data protected 
  41.  * by the monitor lock).  The condition variable is an extern so that it 
  42.  * can be referenced by Proc_Dump().
  43.  */
  44. Boolean            recov_AbsoluteIntervals = TRUE;
  45. Timer_QueueElement    recovIntervalElement;
  46. Sync_Condition        recovPingCondition;
  47. static Sync_Lock    recovPingConditionLock;
  48. /*
  49.  * A list of hosts to ping is used by Recov_Proc.
  50.  */
  51. typedef struct RecovPing {
  52.     List_Links links;
  53.     int spriteID;    /* The host we are interested in */
  54.     Boolean active;    /* TRUE if we are really interested in it */
  55. } RecovPing;
  56.  
  57. List_Links recovPingListHdr;
  58. List_Links *recovPingList = &recovPingListHdr;
  59. /*
  60.  * Access to the ping list is monitored
  61.  */
  62. static Sync_Lock pingListLock;
  63. #define LOCKPTR (&pingListLock)
  64.  
  65. static RecovPing *FirstHostToCheck _ARGS_((void));
  66. static RecovPing *NextHostToCheck _ARGS_((RecovPing *pingPtr));
  67. static void Deactivate _ARGS_((RecovPing *pingPtr));
  68. static void PingInterval _ARGS_((Timer_Ticks time, ClientData clientData));
  69.  
  70.  
  71. /*
  72.  *----------------------------------------------------------------------
  73.  *
  74.  * PingInterval --
  75.  *
  76.  *    Set up the callback routine used for recov pinging.
  77.  *
  78.  * Results:
  79.  *    None.
  80.  *
  81.  * Side effects:
  82.  *    None.
  83.  *
  84.  *----------------------------------------------------------------------
  85.  */
  86. /*ARGSUSED*/
  87. static void
  88. PingInterval(time, clientData)
  89.     Timer_Ticks    time;
  90.     ClientData    clientData;
  91. {
  92.     (void)Sync_GetLock(&recovPingConditionLock);
  93.     Sync_Broadcast(&recovPingCondition);
  94.     (void)Sync_Unlock(&recovPingConditionLock);
  95.     Timer_ScheduleRoutine(&recovIntervalElement, TRUE);
  96.  
  97.     return;
  98. }
  99.  
  100.  
  101. /*
  102.  *----------------------------------------------------------------------
  103.  *
  104.  * RecovPingInit --
  105.  *
  106.  *    Set up the data structures used by the recovery ping process.
  107.  *
  108.  * Results:
  109.  *    None.
  110.  *
  111.  * Side effects:
  112.  *    None.
  113.  *
  114.  *----------------------------------------------------------------------
  115.  */
  116.  
  117. void
  118. RecovPingInit()
  119. {
  120.     Sync_LockInitDynamic(&pingListLock, "Recov:pingListLock");
  121.     Sync_LockInitDynamic(&recovPingConditionLock,
  122.              "Recov:recovPingConditionLock");
  123.     List_Init(recovPingList);
  124.     if (recov_AbsoluteIntervals) {
  125.     recovIntervalElement.routine = PingInterval;
  126.     recovIntervalElement.clientData = 0;
  127.     recovIntervalElement.interval =
  128.         timer_IntOneSecond * recovPingSeconds;
  129.     Timer_ScheduleRoutine(&recovIntervalElement, TRUE);
  130.     }
  131.     return;
  132. }
  133.  
  134.  
  135.  
  136. /*
  137.  *----------------------------------------------------------------------
  138.  *
  139.  * Recov_Proc --
  140.  *
  141.  *    Recovery process that periodically pings other hosts to verify
  142.  *    that they are still and if they have rebooted since we last
  143.  *    heard from them.
  144.  *
  145.  * Results:
  146.  *    None.
  147.  *
  148.  * Side effects:
  149.  *    None.
  150.  *
  151.  *----------------------------------------------------------------------
  152.  */
  153.  
  154. void
  155. Recov_Proc()
  156. {
  157.     RecovPing *pingPtr;
  158.     Time wait;
  159.     int check;
  160.  
  161.     while (TRUE) {
  162.     /*
  163.      * Calculate wait period inside loop so we can change it
  164.      * on the fly.
  165.      */
  166.     if (!recov_AbsoluteIntervals) {
  167.         Time_Multiply(time_OneSecond, recovPingSeconds, &wait);
  168.         Sync_WaitTime(wait);
  169.     } else {
  170.         (void) Sync_GetLock(&recovPingConditionLock);
  171.         (void) Sync_SlowWait(&recovPingCondition, &recovPingConditionLock,
  172.                  FALSE);
  173.         (void) Sync_Unlock(&recovPingConditionLock);
  174.     }
  175.     if (sys_ShuttingDown) {
  176.         printf("Recov_Proc exiting.\n");
  177.         break;
  178.     }
  179.     /*
  180.      * Scan the ping list looking for hosts we should check.
  181.      * We'll ping them if there hasn't been recent message traffic,
  182.      * and we'll deactivate our interest if there is no set
  183.      * of reboot call backs associated with the host.
  184.      */
  185.     pingPtr = FirstHostToCheck();
  186.     while (pingPtr != (RecovPing *)NIL) {
  187.         check = RecovCheckHost(pingPtr->spriteID);
  188.         if (check > 0) {
  189.         RECOV_TRACE(pingPtr->spriteID,
  190.             RecovGetLastHostState(pingPtr->spriteID),
  191.             RECOV_CUZ_PING_CHK);
  192.         recov_Stats.pings++;
  193.         Rpc_Ping(pingPtr->spriteID);
  194.         } else if (check == 0) {
  195.         recov_Stats.pingsSuppressed++;
  196.         } else {
  197.         Deactivate(pingPtr);
  198.         }
  199.         pingPtr = NextHostToCheck(pingPtr);
  200.     }
  201.     }
  202.     Proc_Exit(0);
  203. }
  204.  
  205. /*
  206.  *----------------------------------------------------------------------
  207.  *
  208.  * FirstHostToCheck --
  209.  *
  210.  *    This pulls the first host to check off the ping list.
  211.  *
  212.  * Results:
  213.  *    A pingPtr.
  214.  *
  215.  * Side effects:
  216.  *    None.
  217.  *
  218.  *----------------------------------------------------------------------
  219.  */
  220.  
  221. static RecovPing *
  222. FirstHostToCheck()
  223. {
  224.     RecovPing *pingPtr;
  225.  
  226.     LOCK_MONITOR;
  227.  
  228.     if (List_IsEmpty(recovPingList)) {
  229.     pingPtr = (RecovPing *)NIL;
  230.     } else {
  231.     pingPtr = (RecovPing *)List_First(recovPingList);
  232.     }
  233.  
  234.     UNLOCK_MONITOR;
  235.     return(pingPtr);
  236. }
  237.  
  238. /*
  239.  *----------------------------------------------------------------------
  240.  *
  241.  * NextHostToCheck --
  242.  *
  243.  *    This pulls the next host to check off the ping list.
  244.  *
  245.  * Results:
  246.  *    A pingPtr.
  247.  *
  248.  * Side effects:
  249.  *    None.
  250.  *
  251.  *----------------------------------------------------------------------
  252.  */
  253.  
  254. static RecovPing *
  255. NextHostToCheck(pingPtr)
  256.     RecovPing *pingPtr;
  257. {
  258.     LOCK_MONITOR;
  259.  
  260.     pingPtr = (RecovPing *)List_Next((List_Links *)pingPtr);
  261.     if (List_IsAtEnd(recovPingList, (List_Links *)pingPtr)) {
  262.     pingPtr = (RecovPing *)NIL;
  263.     }
  264.  
  265.     UNLOCK_MONITOR;
  266.     return(pingPtr);
  267. }
  268.  
  269. /*
  270.  *----------------------------------------------------------------------
  271.  *
  272.  * RecovAddHostToPing --
  273.  *
  274.  *    Add an entry to the ping list.
  275.  *
  276.  * Results:
  277.  *    None.
  278.  *
  279.  * Side effects:
  280.  *    List_Insert.
  281.  *
  282.  *----------------------------------------------------------------------
  283.  */
  284.  
  285. void
  286. RecovAddHostToPing(spriteID)
  287.     int spriteID;
  288. {
  289.     RecovPing *pingPtr;
  290.     LOCK_MONITOR;
  291.  
  292.     LIST_FORALL(recovPingList, (List_Links *)pingPtr) {
  293.     if (pingPtr->spriteID == spriteID) {
  294.         if (!pingPtr->active) {
  295.         recov_Stats.numHostsPinged++;
  296.         pingPtr->active = TRUE;
  297.         }
  298.         UNLOCK_MONITOR;
  299.         return;
  300.     }
  301.     }
  302.     pingPtr = (RecovPing *)malloc(sizeof(RecovPing));
  303.     recov_Stats.numHostsPinged++;
  304.     pingPtr->active = TRUE;
  305.     pingPtr->spriteID = spriteID;
  306.     List_InitElement((List_Links *)pingPtr);
  307.     List_Insert((List_Links *)pingPtr, LIST_ATREAR(recovPingList));
  308.  
  309.     UNLOCK_MONITOR;
  310. }
  311.  
  312. /*
  313.  *----------------------------------------------------------------------
  314.  *
  315.  * Deactivate --
  316.  *
  317.  *    Deactivate an entry on the ping list.
  318.  *
  319.  * Results:
  320.  *    None.
  321.  *
  322.  * Side effects:
  323.  *    List_Insert.
  324.  *
  325.  *----------------------------------------------------------------------
  326.  */
  327.  
  328. static void
  329. Deactivate(pingPtr)
  330.     RecovPing *pingPtr;
  331. {
  332.     LOCK_MONITOR;
  333.  
  334.     if (pingPtr->active) {
  335.     recov_Stats.numHostsPinged--;
  336.     pingPtr->active = FALSE;
  337.     }
  338.  
  339.     UNLOCK_MONITOR;
  340.  
  341. }
  342.  
  343. ENTRY void
  344. RecovPrintPingList()
  345. {
  346.     RecovPing *pingPtr;
  347.  
  348.     LOCK_MONITOR;
  349.  
  350.     if (List_IsEmpty(recovPingList)) {
  351.     return;
  352.     } 
  353.     printf("\nPING_LIST\n");
  354.     for (pingPtr = (RecovPing *)List_First(recovPingList);
  355.         !List_IsAtEnd(recovPingList, (List_Links *)pingPtr);
  356.         pingPtr = (RecovPing *)List_Next((List_Links *)pingPtr)) {
  357.     printf("host %d is %s\n", pingPtr->spriteID,
  358.         pingPtr->active ? "active" : "inactive");
  359.     }
  360.      
  361.     UNLOCK_MONITOR;
  362.  
  363.     return;
  364. }
  365.